﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Net_SCADA
{
    public partial class Form_History : Form
    {
        private int QueryType=0;
        private DataTable BoxDetail=new DataTable();
        private int YAxisHeight=30;
        private bool isEmptyBox;
        private DateTime StartTime=new DateTime();
        private DateTime EndTime=new DateTime();
        private float[,] BoxData;
        private float[,] limit=new float[2,5];
        private int[] ZoneStartIntervalMinutes;
        private int CurveHeight=100;
        private int Xscale=1;
        private Label[] lbl_AxisLeft=new Label[6];
        private Label[] lbl_AxisRight=new Label[6];
        private List<ZoneData> z=new List<ZoneData>();
        Ini inifile = new Ini(Application.StartupPath + @"\Settings\Curve.dat");
        private int SelectPanelCols=8;
        private int SelectPanelHeight=42;
        string[] his_AlarmTitle=new string[5]{ "序号","警报名称", "警报等级","发生时间" ,"消除时间"};
        private bool isLoadInterface=false;
        private Label TimeLine=new Label(){ Width=1,BackColor=Color.Black,Height=300,Location=new Point()};
        private Label TimeLabel=new Label(){ AutoSize=true,BackColor=Color.Transparent,ForeColor=Color.Green};
        private Label TimeData=new Label(){ AutoSize=true,BackColor=Color.Transparent,ForeColor=Color.Green};
        private List<Label> Equiplbl=new List<Label>();

        private Dictionary<int,CurveSetting> LineSetting=new Dictionary<int, CurveSetting>();
        private Dictionary<int,float[]> LineData=new Dictionary<int, float[]>();
        Dictionary<CheckBox,List<CheckBox>> ZoneGroup=new Dictionary<CheckBox, List<CheckBox>>();
        Button SelectedButton;


        public Form_History()
        {
            InitializeComponent();
        }

        private void Form_History_Load(object sender , EventArgs e)
        {
            isLoadInterface = true;
            netForms.SetPostionAndSize(this);
            this.Show();
            LoadInterface();
            LoadBoxCurveSetting();
            LoadBoxKeyTimeInterface();
            LoadBoxInfoInterface();
            LoadAlarmInterface();
            LoadDayCurveSetting();
            LoadDayQueryButton();
            isLoadInterface = false;
            dtp_Day_ValueChanged(null,null );
        }

        private void LoadInterface()
        {
            cmb_QueryType.Items.Add("日期料框查询");
            cmb_QueryType.Items.Add("日期曲线查询");
            cmb_QueryType.Items.Add("日期警报查询");
            cmb_QueryType.SelectedIndex = 0;

            pnl_AlarmQuery.Size= pnl_DayQuery.Size= pnl_BoxQuery.Size = new Size(this.Width , this.Height - 33);
            pnl_AlarmQuery.Location= pnl_DayQuery.Location = pnl_BoxQuery.Location;
            grdProduct.Size= lvKeyTime.Size = new Size((this.Width - 15)/2 , 335);
            lbl_ListTitle.Top = lbl_BoxInfoTitle.Top =  2;
            lbl_ListTitle.Left = 5;
            grdProduct.Location = new Point(5 , lbl_ListTitle.Height +lbl_ListTitle.Top + 2);
            lvKeyTime.Location = new Point(lvKeyTime.Width+10, lbl_ListTitle.Height + lbl_ListTitle.Top + 2);
            lbl_BoxInfoTitle.Left = lvKeyTime.Left;
            lbl_ListTitle.Text = dtp_Day.Value.ToString("yyyy年MM月dd日 生产信息");
            pnl_Curve.Location = new Point(0 , grdProduct.Top + grdProduct.Height + 5);
            pnl_Curve.Size = new Size(this.Width , this.Height - pnl_BoxInfo.Height - grdProduct.Top - grdProduct.Height - 5);
            pic_Curve.Location = new Point(pic_AxisL.Width , 0);
            pic_Curve.Size = new Size(pnl_Curve.Width - pic_AxisL.Width-pic_AxisR.Width , pnl_Curve.Height);
            lbl_TempTitle.Parent = pic_AxisL; 
            lbl_CPTitle.Parent = pic_AxisR;
            lbl_CPTitle.Location= lbl_TempTitle.Location = new Point(5 , 30);
            for (int i = 0 ; i < lbl_AxisLeft.Length ; i++)
            {
                pic_AxisL.Controls.Add(lbl_AxisLeft[i] = new Label()
                {
                    Size = new Size(pic_AxisL.Width , 16) ,
                    TextAlign = ContentAlignment.TopRight
                });
                pic_AxisR.Controls.Add(lbl_AxisRight[i]=new Label() {
                    Size = new Size(pic_AxisR.Width , 16) ,
                    TextAlign = ContentAlignment.TopLeft
                });
            }
            dtp_Day.Left = this.Width - dtp_Day.Width - 2;
            cmb_QueryType.Top = dtp_Day.Top;
            cmb_QueryType.Left = dtp_Day.Left - cmb_QueryType.Width - 5;
        }

        private void LoadDayQueryButton()
        {
            string[] groupid=DBOperate.GetZoneMonitorGroupUsed();
            if (groupid == null || groupid.Length <= 0) return;
            DataTable dtGroup=DBOperate.GetDesignGroupSet();
            if (dtGroup == null || dtGroup.Rows.Count <= 0) return;
            for (int i = groupid.Length-1 ; i >= 0 ; i--)
            {
                Button btn=new Button()
                {
                    Size=netForms.sz,
                    Text=dtGroup.Select("groupid=" + groupid[i])[0]["groupname"].ToString() ,
                    Font=netForms.ft,
                    FlatStyle=FlatStyle.Flat,
                    Location=new Point(5+i*(netForms.sz.Width+5),1),
                    Tag= groupid[i]
                };
                btn.Click += Btn_Click;
                SelectedButton = btn;
                pnl_Equip.Controls.Add(btn);
            }
        }

        private void Btn_Click(object sender , EventArgs e)
        {
            int w=(pnl_DayInfo.Width -5* SelectPanelCols -5)/SelectPanelCols;
            Button btn=sender as Button;
            SelectedButton = btn;
            pnl_DayInfo.Controls.Clear();
            ZoneGroup.Clear();
            if (int.TryParse(btn.Tag.ToString() , out int groupid))
            {
                int totalzones=0;
                for (int i = 0 ; i < NetLine.zone.Count ; i++)
                {
                    if (NetLine.zone[i].GroupID == groupid && NetLine.zone[i].isShowCurve)
                    {
                        Panel pnl =new Panel(){
                            Size=new Size(w,SelectPanelHeight),
                            Location=new Point(5+(w+5)*(totalzones%SelectPanelCols),5+(SelectPanelHeight+5)*(totalzones/SelectPanelCols)),
                            BorderStyle=BorderStyle.FixedSingle,
                            BackColor=Color.LightYellow
                        };
                        CheckBox chk=new CheckBox()
                        {
                            Text=NetLine.zone[i].ZoneName,
                            AutoSize=true,
                            Location=new Point(3,1),
                            Checked=GetZoneCurveSelection(NetLine.zone[i].ID),
                            Tag=NetLine.zone[i].ID,
                        };
                        chk.CheckedChanged += EquipChk_CheckedChanged;
                        pnl.Controls.Add(chk);
                        ZoneGroup.Add(chk , new List<CheckBox>());
                        if (NetLine.zone[i].pv != null)
                        {
                            ZoneGroup[chk].Add(CreateCheckBox("pv" , new Size(w / 3 - SelectPanelHeight/2 , SelectPanelHeight/2) , new Point(SelectPanelHeight/2 , SelectPanelHeight/2) , NetLine.zone[i].pv.ID,LineSetting[NetLine.zone[i].pv.ID].isshow));
                            pnl.Controls.Add(ZoneGroup[chk].Last());
                            pnl.Controls.Add(CreateLabel(new Point( 1 , SelectPanelHeight/2+1) , LineSetting[NetLine.zone[i].pv.ID].CurveColor , NetLine.zone[i].pv.ID));
                        }
                        if (NetLine.zone[i].sv != null)
                        {
                            ZoneGroup[chk].Add(CreateCheckBox("sv" , new Size(w / 3 - SelectPanelHeight / 2 , SelectPanelHeight / 2) , new Point(w / 3 + SelectPanelHeight / 2 , SelectPanelHeight / 2) , NetLine.zone[i].sv.ID, LineSetting[NetLine.zone[i].sv.ID].isshow));
                            pnl.Controls.Add(ZoneGroup[chk].Last());
                            pnl.Controls.Add(CreateLabel(new Point( w / 3 + 1 , SelectPanelHeight / 2+1) , LineSetting[NetLine.zone[i].sv.ID].CurveColor , NetLine.zone[i].sv.ID));
                        }
                        if (NetLine.zone[i].ovpv != null)
                        {
                            ZoneGroup[chk].Add(CreateCheckBox("ovpv" , new Size(w / 3 - SelectPanelHeight / 2 , SelectPanelHeight / 2) , new Point(2 * w / 3 + SelectPanelHeight / 2 , SelectPanelHeight / 2) , NetLine.zone[i].ovpv.ID, LineSetting[NetLine.zone[i].ovpv.ID].isshow));
                            pnl.Controls.Add(ZoneGroup[chk].Last());
                            pnl.Controls.Add(CreateLabel(new Point(2 * w / 3 + 1 , SelectPanelHeight / 2 + 1) , LineSetting[NetLine.zone[i].ovpv.ID].CurveColor , NetLine.zone[i].ovpv.ID));
                        }
                        pnl_DayInfo.Controls.Add(pnl);
                        totalzones++;
                    }
                }
            }
            showCurveByDay();
        }

        private bool GetZoneCurveSelection(int zoneid)
        {
            Ini ZoneCurveSet=new Ini(Application.StartupPath+"\\settings\\Curve.dat");
            bool isshow=true;
            if (int.TryParse(ZoneCurveSet.ReadValue("Zone" + zoneid , "isshow") , out int c))
                isshow = c == 1 ? true : false;
            return isshow;
        }
        private void SetZoneCurveSelection(int zoneid,bool value)
        {
            Ini ZoneCurveSet=new Ini(Application.StartupPath+"\\settings\\Curve.dat");
            ZoneCurveSet.Write("Zone" + zoneid , "isshow" , value ? "1" : "0");
        }

        private CheckBox CreateCheckBox(string txt,Size sz,Point pt,object tag,bool value)
        {
            CheckBox chk=new CheckBox(){
                Text = txt,
                Size = sz ,
                Location = pt,
                Checked=value,
                Tag = tag
            };
            chk.CheckedChanged += ItemChk_CheckedChanged;
            return chk;
        }

        private void ItemChk_CheckedChanged(object sender , EventArgs e)
        {
            CheckBox chk=sender as CheckBox;
            int.TryParse(chk.Tag.ToString() , out int itemid);
            if (itemid != 0)
            {
                LineSetting[itemid].isshow = chk.Checked;
                LineSetting[itemid].SaveCurveSetting();
                showCurveByDay();
            }
        }

        private Label CreateLabel(Point pt,Color bgColor,object tag)
        {
            Label lbl=new Label()
            {
                Size = new Size(16 , 16) ,
                Location = pt ,
                Tag = tag ,
                BackColor = bgColor
            };
            lbl.Click += ColorLbl_Click;
            return lbl;
        }

        private void ColorLbl_Click(object sender , EventArgs e)
        {
            Label lbl =sender as Label;
            int.TryParse(lbl.Tag.ToString() , out int itemid);
            if (itemid != 0)
            {
                ColorDialog cd=new ColorDialog();
                cd.Color = lbl.BackColor;
                DialogResult res=cd.ShowDialog();
                if (res == DialogResult.OK)
                {
                    lbl.BackColor = cd.Color;
                    LineSetting[itemid].CurveColor = lbl.BackColor;
                    LineSetting[itemid].SaveCurveSetting();
                    showCurveByDay();
                }
            }            
        }

        private void EquipChk_CheckedChanged(object sender , EventArgs e)
        {
            CheckBox chk=sender as CheckBox;
            int.TryParse(chk.Tag.ToString() , out int zoneid);
            if (zoneid != 0)
                SetZoneCurveSelection(zoneid , chk.Checked);
            showCurveByDay();
        }

        private void LoadBoxCurveSetting()
        {
            //显示物料box的设置
            for (int i = 0 ; i < 5 ; i++)
            {
                limit[0,i]= Convert.ToInt32("0" + inifile.ReadValue("BoxCurve" + i , "Min"));
                limit[1,i]= Convert.ToInt32("0" + inifile.ReadValue("BoxCurve" + i , "Max"));
                z.Add(new ZoneData());
                z[i].Width = 200;
                z[i].Location = new Point((200 + (this.Width - 1000) / 6) * (i + 1) - 200 , 10);
                z[i].lbl_Name.Text = inifile.ReadValue("BoxCurve" + i , "Name")+"("+ inifile.ReadValue("BoxCurve" + i , "Unit")+")";
                z[i].chk_ShowItem.Checked= inifile.ReadValue("BoxCurve" + i , "Selected") == "1" ? true : false;
                z[i].lbl_Color.BackColor= Color.FromArgb(Convert.ToInt32(inifile.ReadValue("BoxCurve" + i , "Color")));
                z[i].CheckSelect += ZoneData_CheckSelect;
                z[i].ColorSelect += ZoneData_ColorSelect;
                z[i].Tag = i;
                pnl_BoxInfo.Controls.Add(z.Last());
            }
            z[4].lbl_Value.Text = "";
            
        }
        private void LoadDayCurveSetting()
        {//显示天数据时的设置

            for (int i = 0 ; i < NetLine.zone.Count ; i++)
            {
                if (NetLine.zone[i].isShowCurve)
                {
                    if (NetLine.zone[i].pv != null)
                    {
                        LineSetting.Add(NetLine.zone[i].pv.ID , new CurveSetting(NetLine.zone[i].pv.ID));
                        LineData.Add(NetLine.zone[i].pv.ID , new float[pic_Curve.Width]);
                    }
                    if (NetLine.zone[i].sv != null)
                    {
                        LineSetting.Add(NetLine.zone[i].sv.ID , new CurveSetting(NetLine.zone[i].sv.ID));
                        LineData.Add(NetLine.zone[i].sv.ID , new float[pic_Curve.Width]);
                    }
                    if (NetLine.zone[i].ovpv != null)
                    {
                        LineSetting.Add(NetLine.zone[i].ovpv.ID , new CurveSetting(NetLine.zone[i].ovpv.ID));
                        LineData.Add(NetLine.zone[i].ovpv.ID , new float[pic_Curve.Width]);
                    }
                }
            }

        }

        //修改颜色
        private void ZoneData_ColorSelect(object sender , EventArgs e)
        {
            Label lbl = (Label)sender;
            ZoneData zd = (ZoneData)lbl.Parent;
            ColorDialog cd=new ColorDialog();
            cd.Color = zd.lbl_Color.BackColor;
            if (cd.ShowDialog() == DialogResult.OK)
            {
                zd.lbl_Color.BackColor = cd.Color;
                inifile.Write("BoxCurve" + zd.Tag.ToString() , "Color" , zd.lbl_Color.BackColor.ToArgb().ToString());
                ShowBoxCurve();
            }

        }
        private void ZoneData_CheckSelect(object sender , EventArgs e)
        {
            CheckBox cb = (CheckBox)sender;
            ZoneData zd = (ZoneData)cb.Parent;
            inifile.Write("BoxCurve" + zd.Tag.ToString() , "Selected" , zd.chk_ShowItem.Checked ? "1" : "0");
            ShowBoxCurve();
        }

        private void LoadBoxInfoInterface()
        {
            grdProduct.Columns.Add("index" , "序号");
            grdProduct.Columns.Add("box" , "料框");
            grdProduct.Columns.Add("mark" , "标记");
            grdProduct.Columns.Add("batchserial" , "批次编号");
            grdProduct.Columns.Add("createuser" , "创建用户");
            grdProduct.Columns.Add("loadtime" , "加载时间");
            grdProduct.Columns.Add("info0" , "产品名称");
            grdProduct.Columns.Add("ProductVersion" , "ProductVersion");
            grdProduct.Columns["ProductVersion"].Visible = false;
            grdProduct.Columns["mark"].Visible = false;
            grdProduct.Columns["index"].Width = 60;
            grdProduct.Columns["box"].Width= 60;
            grdProduct.Columns["batchserial"].Width = 150;
            grdProduct.Columns["createuser"].Width = 150;
            grdProduct.Columns["loadtime"].Width = 150;
            grdProduct.Columns["info0"].Width = 150;
            for (int i = 0 ; i < grdProduct.Columns.Count ; i++)
            {
                grdProduct.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
            }
        }
        private void LoadBoxKeyTimeInterface()
        {
            lvKeyTime.Columns.Add("序号" , 40 , HorizontalAlignment.Center);
            lvKeyTime.Columns.Add("设备分区" , lvKeyTime.Width - 542 , HorizontalAlignment.Center);
            lvKeyTime.Columns.Add("进入时间" , 200 , HorizontalAlignment.Center);
            lvKeyTime.Columns.Add("移出时间" , 200 , HorizontalAlignment.Center);
            lvKeyTime.Columns.Add("停留时间" , 80 , HorizontalAlignment.Center);
            for (int i = 0 ; i < NetLine.BoxKeyTime.Count ; i++)
            {
                lvKeyTime.Items.Add(new ListViewItem(new string[] { (i + 1).ToString() , NetLine. BoxKeyTime[i].KeyTimeName , "-" , "-" , "-" }));
            }
        }
        private void SetBoxKeyTime()
        {
            if (grdProduct.SelectedRows != null)
            {
                isEmptyBox = false;
                lbl_BoxInfoTitle.Text = grdProduct.SelectedRows[0].Cells["box"].Value.ToString() + " 号料框信息";
                DateTime dt1,dt2;
                for (int i = 0 ; i < NetLine. BoxKeyTime.Count ; i++)
                {
                    DateTime.TryParse(BoxDetail.Rows[grdProduct.SelectedRows[0].Index ]["keytime" + NetLine.BoxKeyTime[i].KeyTimeInIndex].ToString() , out dt1);
                    DateTime.TryParse(BoxDetail.Rows[grdProduct.SelectedRows[0].Index]["keytime" + NetLine.BoxKeyTime[i].KeyTimeOutIndex].ToString() , out dt2);
                    NetLine.BoxKeyTime[i].MoveInTime = dt1;
                    NetLine.BoxKeyTime[i].MoveOutTime = dt2;
                    bool isok1 = !( dt1.Year < 2021);
                    lvKeyTime.Items[i].SubItems[2].Text = isok1 ? dt1.ToString("yyyy-MM-dd HH:mm:ss") : "-";
                    bool isok2 =!(dt2.Year < 2021);
                    lvKeyTime.Items[i].SubItems[3].Text = isok2 ? dt2.ToString("yyyy-MM-dd HH:mm:ss") : "-";
                    if (isok1 && isok2)
                    {
                        TimeSpan ts= dt2.Subtract(dt1);
                        lvKeyTime.Items[i].SubItems[4].Text = (new StringBuilder(ts.Hours.ToString()).Append(":").Append(ts.Minutes).Append(":").Append(ts.Seconds)).ToString();
                    }
                    else
                        lvKeyTime.Items[i].SubItems[4].Text = "-";
                }
            }
            else
            {
                isEmptyBox = true;
                lbl_BoxInfoTitle.Text = "-";
                for (int i = 0 ; i < NetLine.BoxKeyTime.Count ; i++)
                {
                    lvKeyTime.Items[i].SubItems[2].Text = lvKeyTime.Items[i].SubItems[3].Text = "-";
                }
            }
            ShowBoxCurve();
        }

        private void LoadDayCurveInfoControls()
        {
            TimeLine.Height = pic_Curve.Height - 31;
            TimeLabel.Text = StartTime.ToString("yyyy-MM-dd HH:mm");
            
            pic_Curve.Controls.Add(TimeLine);
            pic_Curve.Controls.Add(TimeData);
            pic_Curve.Controls.Add(TimeLabel);
            TimeLabel.Top = pic_Curve.Height - 32 - TimeLabel.Height;
        }
        private void RemoveEquipLabels()
        {
            pic_Curve.Controls.Clear();
            if (Equiplbl.Count > 0)
            {
                foreach (Label item in Equiplbl)
                    item.Dispose();
            }
            Equiplbl.Clear();
        }
        private void showCurveByDay()
        {
            pic_Curve.Image = null;
            RemoveEquipLabels();
            Xscale = 1;
            int totalminutes = 1440;
            if (totalminutes < pic_Curve.Width)
            {
                totalminutes = pic_Curve.Width;
            }
            hScroll.Visible = totalminutes > pic_Curve.Width;//这里需要增加设置滚动条的范围。
            Bitmap  bm = new Bitmap(totalminutes , pic_Curve.Height);
            DrawBgGrid(bm);
            foreach (CheckBox chk in ZoneGroup.Keys)
            {
                if (chk.Checked)
                {
                    foreach (CheckBox itemchk in ZoneGroup[chk])
                    {
                        if (itemchk.Checked)
                        {
                            if (int.TryParse(itemchk.Tag.ToString() , out int itemid))
                            {
                                DrawOneCurve(bm,itemid);
                            }
                        }
                    }
                }
            }
            pic_Curve.Image = bm;
            LoadDayCurveInfoControls();
        }
        private void showAlarmByDay(DateTime SearchDay)
        {
            LoadAlarmData(SearchDay.Date);
        }
        private void showProcessBoxbyDay(DateTime SearchDay)
        {
            grdProduct.Rows.Clear();
            BoxDetail = DBOperate.GetProcessBoxByTime(SearchDay.Date,SearchDay.AddDays(1).Date.AddSeconds(-1));
            if (BoxDetail == null || BoxDetail.Rows.Count == 0) return;
            grdProduct.Rows.Add(BoxDetail.Rows.Count);
            for (int i = 0 ; i < BoxDetail.Rows.Count ; i++)
            {
                grdProduct.Rows[i].Cells[0].Value = i + 1;
                for (int j = 1 ; j < grdProduct.Columns.Count ; j++)
                {
                    grdProduct.Rows[i].Cells[j].Value = BoxDetail.Rows[i][grdProduct.Columns[j].Name];
                }
            }
        }

        //将数据生成曲线并显示
        private void ShowBoxCurve()
        {
            if (isEmptyBox) return;
            pic_Curve.Image = null;
            pic_Curve.Controls.Clear();
            BoxData=GetBoxData(out StartTime , out EndTime);
            if (BoxData == null) return;
            //获取总时间，来确定pic_Curve的宽度，滚动条是否显示
            Xscale = 1;
            int totalminute=(int)EndTime.Subtract(StartTime).TotalMinutes;
            if (totalminute <= pic_Curve.Width)
            {
                if (totalminute != 0) Xscale = pic_Curve.Width / totalminute;
                totalminute = pic_Curve.Width;
            }
            hScroll.Visible = totalminute > pic_Curve.Width;
            Bitmap bm=new Bitmap(totalminute,pic_Curve.Height);

            DrawBgGrid(bm);
            if (BoxData.Length == 0)
            {
                pic_Curve.Image = bm;
                return;
            }
            DrawBoxLines(bm);
            pic_Curve.Image = bm;
        }
        //准备用来画曲线的数据
        private float[,] GetBoxData(out DateTime StartTime, out DateTime EndTime)
        {
            DateTime starttime=new DateTime(),endtime=new DateTime();
            DataTable[] datatable=new DataTable[NetLine.BoxKeyTime.Count];
            List<int> ids=new List<int>();
            ZoneStartIntervalMinutes = new int[NetLine.BoxKeyTime.Count];
            for (int i = 0 ; i < NetLine.BoxKeyTime.Count ; i++)
            {
                if (NetLine.BoxKeyTime[i].ZoneID.Count == 0) continue;
                if (NetLine.BoxKeyTime[i].MoveInTime.Year>2020 && NetLine.BoxKeyTime[i].MoveOutTime.Year > 2020)
                {
                    if (starttime.Year < 2021) starttime = NetLine.BoxKeyTime[i].MoveInTime;
                    endtime = NetLine.BoxKeyTime[i].MoveOutTime;
                    ZoneStartIntervalMinutes[i] =(int)NetLine.BoxKeyTime[i].MoveInTime.Subtract(starttime).TotalMinutes;
                    ids.Clear();
                    for (int j = 0 ; j < NetLine.BoxKeyTime[i].ZoneID.Count ; j++)
                    {
                        ids.Add(NetLine.BoxKeyTime[i].ZoneID[j][0]); 
                        ids.Add(NetLine.BoxKeyTime[i].ZoneID[j][1]);
                    }
                    datatable[i] = DBOperate.GetParameterData(NetLine.BoxKeyTime[i].MoveInTime , NetLine.BoxKeyTime[i].MoveOutTime , ids);
                }
            }
            int totalminutes=(int)endtime.Subtract(starttime).TotalMinutes;
            StartTime = starttime;
            EndTime = endtime;
            if (totalminutes <= 0) return null;
            float[,] recorderdata=new float[totalminutes,4];
            for (int i = 0 ; i < datatable.Length ; i++)
            {
                if (datatable[i] == null || datatable[i].Rows.Count == 0) continue;
                for (int j = 0 ; j < datatable[i].Rows.Count ; j++)
                {
                    if (DateTime.TryParse(datatable[i].Rows[j]["savetime"].ToString() , out endtime))
                    {
                        int minutediv = (int)endtime.Subtract(starttime).TotalMinutes;
                        if (minutediv >= 0 && minutediv < totalminutes)
                            for (int k = 1 ; k < datatable[i].Columns.Count && k < 5 ; k++)
                            {
                                float.TryParse(datatable[i].Rows[j][k].ToString() , out float val);
                                recorderdata[minutediv , k - 1] = val;
                            }
                    }
                }
            }

            return recorderdata;
        }
        #region 绘制天的曲线
        /// <summary>
        /// 获取每天的数据
        /// </summary>
        private void GetDayData(DateTime SearchDay)
        {
            int totalminutes=pic_Curve.Width;
            if (totalminutes < 1440) totalminutes = 1440;
            DataTable dt =DBOperate.GetParameterData(SearchDay.Date,SearchDay.Date.AddMinutes(totalminutes));
            StartTime=SearchDay.Date;
            DateTime edTime;
            int minuteinterval=0;
            foreach (int itemid in LineData.Keys)
            {
                Array.Clear(LineData[itemid] , 0 , LineData[itemid].Length);
                //LineData[itemid] = new float[totalminutes];
                if (dt==null || dt.Rows.Count ==0) continue;
                for (int i = 0 ; i < dt.Rows.Count ; i++)
                {
                    try
                    {
                        edTime = Convert.ToDateTime(dt.Rows[i]["savetime"]);
                        minuteinterval = (int)edTime.Subtract(StartTime).TotalMinutes;
                        LineData[itemid][minuteinterval] = Convert.ToSingle(dt.Rows[i][itemid.ToString()]);
                    }
                    catch (Exception)
                    {
                        continue;
                    }
                }
            }
        }
        /// <summary>
        /// 绘制曲线
        /// </summary>
        private void DrawOneCurve(Bitmap bm, int ItemIndex)
        {
            Pen p=new Pen(LineSetting[ItemIndex].CurveColor,2);
            Graphics g = Graphics.FromImage(bm);
            float x0, y0, x1, y1;
            x0 = 0;
            y0 = CurveHeight * (LineSetting[ItemIndex].AxisMax - LineData[ItemIndex][0]) / (LineSetting[ItemIndex].AxisMax- LineSetting[ItemIndex].AxisMin);
            for (int j = 1 ; j < LineData[ItemIndex].Length ; j++)
            {
                y1 = CurveHeight * (LineSetting[ItemIndex].AxisMax - LineData[ItemIndex][j]) / (LineSetting[ItemIndex].AxisMax - LineSetting[ItemIndex].AxisMin);
                x1 = j * Xscale;
                if (LineData[ItemIndex][j] * LineData[ItemIndex][j-1] != 0)
                {
                    g.DrawLine(p , x0 , y0 , x1 , y1);
                }
                y0 = y1;
                x0 = x1;
            }
        }
        #endregion
        private void DrawBgGrid(Bitmap bm)
        {
            if (bm.Width == 0 || bm.Height == 0) return;
            int h = bm.Height - YAxisHeight;
            int w=bm.Width;
            //画横向的线
            
            int smallDiv = h  / 50;
            int bigDiv = smallDiv*10;
            h = bigDiv * 5;
            CurveHeight = h;
            Graphics g = Graphics.FromImage(bm);
            Pen p = new Pen(Color.Gray, 1);

            for (int i = 0 ; i < 5 ; i++)
            {
                p.Color = Color.DarkGray;
                g.DrawLine(p , 0 , i * bigDiv ,w  , i * bigDiv);
                lbl_AxisRight[i].Top = lbl_AxisLeft[i].Top = i * bigDiv-5;
                lbl_AxisRight[i].Text = Math.Round(limit[1,2] - limit[1,2] / 5 * i , 2).ToString();
                lbl_AxisLeft[i].Text = Math.Round(limit[1,0] - limit[1,0] / 5 * i , 2).ToString();
                p.Color = Color.LightGray;
                for (int j = 1 ; j < 10 ; j++)
                {
                    g.DrawLine(p , 0 , i * bigDiv + j * smallDiv ,w , i * bigDiv + j * smallDiv);
                }
            }
            p.Color = Color.DarkGray;
            g.DrawLine(p , 0 , h , w , h);
            lbl_AxisRight[0].Top = lbl_AxisLeft[0].Top = 0;
            lbl_AxisRight[5].Top = lbl_AxisLeft[5].Top =h-8;
            lbl_AxisRight[5].Text = lbl_AxisLeft[5].Text = "0";
            //画纵向的线
            SolidBrush brush = new SolidBrush(Color.Black);
            int xIndex = 0;
            int min=0;
            SizeF sf;
            StringBuilder sb;
            while (xIndex * 120 < w)
            {
                p.Color = Color.DarkGray;
                g.DrawLine(p ,  xIndex * 120 , 0 ,  xIndex * 120 , h);
                min = (xIndex * 120) / Xscale;
                //sb = new StringBuilder(xIndex.ToString("00") + ":00");
                sb = new StringBuilder().Append((min / 60).ToString("00")).Append(":").Append((min % 60).ToString("00"));
                sf = fdPublicFunction.GetTextSize(this.Font , sb);
                g.DrawString(sb.ToString() , this.Font , brush , new PointF(xIndex * 120f - sf.Width / 2 , h + 2));
                xIndex++;
            }
            g.DrawLine(p ,  w - 1 , 0 ,  w - 1 , h);
            g.DrawString(StartTime.ToString("yyyy-MM-dd HH:mm:00") , this.Font , brush , new PointF(0 , h + 14));
            string s=StartTime.AddMinutes(bm.Width/Xscale).ToString("yyyy-MM-dd HH:mm:00");
            g.DrawString(s , this.Font , brush , new PointF(bm.Width - g.MeasureString(s , this.Font).Width+2 , h + 14));

            if (QueryType!=0 || !z[4].chk_ShowItem.Checked) return;
            //绘制分区分隔线，并添加文字lbl

            p.Color = z[4].lbl_Color.BackColor;

            if (NetLine.BoxKeyTime[0].MoveInTime.Year >= 2021)
            {
                Label lbl=new Label()
                {
                    BorderStyle=BorderStyle.FixedSingle,
                    Text=NetLine.BoxKeyTime[0].KeyTimeName,
                    Location=new Point(1,0),
                    AutoSize=true,
                };
                pic_Curve.Controls.Add(lbl);
            }

            for (int i = 1 ; i < ZoneStartIntervalMinutes.Length ; i++)
            {
                if (ZoneStartIntervalMinutes[i] > 0)
                {
                    g.DrawLine(p , ZoneStartIntervalMinutes[i] * Xscale , 0 , ZoneStartIntervalMinutes[i] * Xscale , h);
                    Label lbl=new Label(){
                        BorderStyle=BorderStyle.FixedSingle,
                        Text=NetLine.BoxKeyTime[i].KeyTimeName,
                        Location=new Point(ZoneStartIntervalMinutes[i] * Xscale +1,i%3 * 15),
                        AutoSize=true,
                    };
                    Equiplbl.Add(lbl);
                    pic_Curve.Controls.Add(lbl);
                }
            }
        }
        private void DrawBoxLines(Bitmap bm)
        {
            int length=BoxData.Length/4;
            Graphics gp = Graphics.FromImage(bm);
            for (int i = 3 ; i >= 0 ; i--)
            {
                if (!z[i].chk_ShowItem.Checked) continue;
                Pen p=new Pen(z[i].lbl_Color.BackColor,2);
                float x0, y0, x1, y1;
                x0 = 0;
                y0 = CurveHeight * (limit[1,i] - BoxData[0 , i]) / limit[1,i];
                for (int j = 1 ; j < length ; j++)
                {
                    y1 = CurveHeight * (limit[1,i] - BoxData[j , i]) / limit[1,i];
                    x1 = j* Xscale;
                    //if (BoxData[j , i] * BoxData[j - 1 , i] != 0)
                    {
                        gp.DrawLine(p , x0 , y0 , x1 , y1);
                    }
                    y0 = y1;
                    x0 = x1;
                }
            }
        }

        private void dtp_Day_ValueChanged(object sender , EventArgs e)
        {
            if (isLoadInterface) return;
            if (QueryType == 0)//按天查询box，显示相关批次信息，
            {
                showProcessBoxbyDay(dtp_Day.Value);
                if (grdProduct.Rows.Count > 0)
                {
                    lbl_ListTitle.Text = dtp_Day.Value.ToString("yyyy年MM月dd日 生产信息");
                    grdProduct.Rows[0].Selected = true;
                    SetBoxKeyTime();
                }
                else
                {
                    lbl_ListTitle.Text = dtp_Day.Value.ToString("yyyy年MM月dd日 无生产信息");
                }
                return;
            }
            if (QueryType==1)//按天显示每天各个设备的数据
            {
                GetDayData(dtp_Day.Value);
                Btn_Click(SelectedButton , null);
            }
            if (QueryType == 2)//按天显示每天的警报数据
            {
                showAlarmByDay(dtp_Day.Value);
            }
        }
        private void grdProduct_CellClick(object sender , DataGridViewCellEventArgs e)
        {
            SetBoxKeyTime();
        }

        private void cmb_QueryType_SelectedIndexChanged(object sender , EventArgs e)
        {
            QueryType = cmb_QueryType.SelectedIndex;

            if (QueryType == 0)
            {
                pnl_BoxQuery.Visible = true;
                pnl_DayQuery.Visible = false;
                pnl_AlarmQuery.Visible = false;
                pnl_Curve.Parent = pnl_BoxQuery;
                pnl_Curve.Location = new Point(0 , grdProduct.Top + grdProduct.Height + 5);
                pnl_Curve.Size = new Size(this.Width , this.Height - pnl_BoxInfo.Height - grdProduct.Top - grdProduct.Height - 5);
                pic_Curve.Location = new Point(pic_AxisL.Width , 0);
                pic_Curve.Size = new Size(pnl_Curve.Width - pic_AxisL.Width - pic_AxisR.Width , pnl_Curve.Height);
                dtp_Day_ValueChanged(null , null);
                return;
            }
            if (QueryType == 1)
            {
                pnl_BoxQuery.Visible = false;
                pnl_DayQuery.Visible = true;
                pnl_AlarmQuery.Visible = false;
                pnl_Curve.Parent = pnl_DayQuery;
                pnl_Curve.Location = new Point(0 ,  5);
                pnl_Curve.Size = new Size(this.Width , pnl_DayQuery.Height -pnl_DayInfo.Height -pnl_Equip.Height  - 5);
                pic_Curve.Location = new Point(pic_AxisL.Width , 0);
                pic_Curve.Size = new Size(pnl_Curve.Width - pic_AxisL.Width - pic_AxisR.Width , pnl_Curve.Height);
                dtp_Day_ValueChanged(null , null);
                return;
            }
            if (QueryType == 2)
            {
                pnl_BoxQuery.Visible = false;
                pnl_DayQuery.Visible =false;
                pnl_AlarmQuery.Visible = true;
                dtp_Day_ValueChanged(null , null);
                return;
            }
        }


        private void LoadAlarmInterface()
        {
            lst_Alarm.Clear();
            lst_Alarm.Location = new Point(2 , 30);
            lst_Alarm.Size = new Size(pnl_AlarmQuery.Width - 4 , pnl_AlarmQuery.Height - 40);
            lst_Alarm.Columns.Add(his_AlarmTitle[0] , 100 , HorizontalAlignment.Left);
            lst_Alarm.Columns.Add(his_AlarmTitle[1] , lst_Alarm.Width - 622 , HorizontalAlignment.Center);
            lst_Alarm.Columns.Add(his_AlarmTitle[2] , 100 , HorizontalAlignment.Left);
            lst_Alarm.Columns.Add(his_AlarmTitle[3] , 200 , HorizontalAlignment.Left);
            lst_Alarm.Columns.Add(his_AlarmTitle[4] , 200 , HorizontalAlignment.Left);
        }

        private void LoadAlarmData(DateTime datetime)
        {
            LoadAlarmInterface();
            DataTable dt = DBOperate.his_GetAlarmValues(datetime, datetime.AddDays(1));

            if (dt == null || dt.Rows.Count == 0) {
                lbl_AlarmQueryTitle.Text = datetime.ToString("yyyy年MM月dd日") + " 没有警报记录";
                return;  
            }
            lbl_AlarmQueryTitle.Text = datetime.ToString("yyyy年MM月dd日") + " 警报记录";
            for (int i = dt.Rows.Count - 1 ; i >= 0 ; i--)
            {
                if (dt.Rows[i]["AlarmActive"].ToString() == "0")
                {
                    lst_Alarm.Items.Add(new ListViewItem(new string[] { (lst_Alarm.Items.Count + 1).ToString() , dt.Rows[i]["AlarmName"].ToString() , dt.Rows[i]["AlarmLevel"].ToString() , "" , dt.Rows[i]["SaveTime"].ToString()}));//最后是报警等级，最后修改
                }
                else
                {
                    //1这里加载数据，对数据进行重组
                    int lastindex = -10;
                    for (int k = lst_Alarm.Items.Count - 1 ; k >= 0 ; k--)
                    {
                        if (dt.Rows[i]["AlarmName"].ToString() == lst_Alarm.Items[k].SubItems[1].Text && lst_Alarm.Items[k].SubItems[3].Text == "")
                        {
                            lst_Alarm.Items[k].SubItems[3].Text = dt.Rows[i]["SaveTime"].ToString();
                            lastindex = k;
                            break;
                        }
                    }
                    if (lastindex == -10)
                    {
                        lst_Alarm.Items.Add(new ListViewItem(new string[] { (lst_Alarm.Items.Count + 1).ToString() , dt.Rows[i]["AlarmName"].ToString() , dt.Rows[i]["AlarmLevel"].ToString() , dt.Rows[i]["SaveTime"].ToString() , ""  }));
                    }
                }
            }
        }

        private void pic_Curve_MouseMove(object sender , MouseEventArgs e)
        {
            if (QueryType == 1)
            {
                TimeLabel.Visible=TimeLine.Visible = TimeData.Visible = true;
                TimeLine.Left = e.X;
                TimeLabel.Text = StartTime.AddMinutes(e.X).ToString("yyyy-MM-dd HH:mm");
                StringBuilder sb=new StringBuilder();
                foreach (CheckBox zonechk in ZoneGroup.Keys)
                {
                    sb.Append(zonechk.Text).Append(":");
                    foreach (CheckBox chk in ZoneGroup[zonechk])
                    {
                        int.TryParse(chk.Tag.ToString() , out int v);
                        sb.Append(chk.Text).Append(":").Append(LineData[v][e.X]).Append(" ");
                    }
                    sb.Append("\n");
                }
                TimeData.Text = sb.ToString();
                if(e.X>pic_Curve.Width / 2)
                {
                    TimeData.Left = e.X - 2 - TimeData.Width;
                    TimeLabel.Left = e.X - 2 - TimeLabel.Width;
                }
                else
                {
                   TimeLabel.Left= TimeData.Left = e.X + 2;
                }
            }
        }

        private void pic_Curve_MouseLeave(object sender , EventArgs e)
        {
            if(QueryType==1)
                TimeData.Visible = TimeLine.Visible = false;
        }
    }
    class CurveSetting
    {
        public float AxisMin { get; set; } = 0;
        public float AxisMax { get; set; } = 1000;
        public Color CurveColor { get; set; } = Color.Black;

        public bool isshow=true;

        private string _sectionID="";

        private Ini Curveset=new Ini(Application.StartupPath+"\\settings\\Curve.dat");

        public CurveSetting(int sectionid)
        {
            _sectionID = sectionid.ToString();
            float v;
            int c;
            if (float.TryParse(Curveset.ReadValue(_sectionID , "AxisMin") , out  v))
                 AxisMin = v;
            if (float.TryParse(Curveset.ReadValue(_sectionID , "AxisMax") , out  v))
                AxisMax = v;
            if(int.TryParse(Curveset.ReadValue(_sectionID , "CurveColor") , out  c))
                CurveColor=Color.FromArgb(c);
            if (int.TryParse(Curveset.ReadValue(_sectionID , "isshow") , out c))
                isshow = c == 0 ? false : true;
        }

        public void SaveCurveSetting()
        {
            if (_sectionID == "") return;
            Curveset.Write(_sectionID , "AxisMin" , AxisMin.ToString());
            Curveset.Write(_sectionID , "AxisMax" , AxisMax.ToString());
            Curveset.Write(_sectionID , "CurveColor" , CurveColor.ToArgb().ToString());
            Curveset.Write(_sectionID , "isshow" , isshow?"1":"0");
        }
    } 
}
